/**
 * @brief Multiplexor that is manage select(Win32), epoll(Linux) or kqueue(FreeBSD).\n
 *
 * @author Huang RuiGuang
 * @date 2008/12/1
 *
 * Herm library
 * Copyright (c) 2008 by Huang RuiGuang(daemon.huang@gmail.com)
 *
 * Permission to use, copy, modify, distribute and sell this software.
 */

#ifndef HERM_SOCKET_MULTIPLEXOR_H
#define HERM_SOCKET_MULTIPLEXOR_H

#if defined WIN32
	#include "select/multiplexor_impl.h"
#elif defined ANDROID
    #include "select/multiplexor_impl.h"
#elif defined __linux__
	#include "epoll/multiplexor_impl.h"
#elif defined __FreeBSD__
	#include "kqueue/multiplexor_impl.h"
#elif defined __APPLE__
    #include "select/multiplexor_impl.h"
#else
	#error "Herm don't support this platform!"
#endif

#ifdef HERM_SOCKET_MULTIPLEXOR_COMMENT
// This Multiplexor is only to comment and don't compile.
class Multiplexor
{
public:
	/**
     * @brief Create manager.
	 * @param [size] Indicate the number of Handler to be managed. The \a size\n
	 *        must >= 0.
	 * @param [timeout] 0, return immediately;
	 *                 -1, wait indefinitely in FreeBSD&Linux Multiplexor, wait 100 milliseconds \a
	 *                     in Windows Multiplexor; 
	 *                 >0, wait \a timeout milliseconds;
	 * @param [lt] Default is Level Triggered. If the value of \a LT is false Multiplexor 
	 *        will be Edge Triggered. Win32 and FreeBSD multiplexor always LT!
     */
	Multiplexor(int size, int timeout = -1, bool lt = true);
	~Multiplexor();

	/**
     * @brief Multiplexor routine entry.
	 * @note Application must call it. And wait indefinitely is default behavior.
	 */
	void Run();

	/**
     * @brief Register io event.
	 * @param [eh] Handler to be registered.
	 * @param [mask] io events.
	 * @exception Occurred error, throw herm::Exception.
	 */
	void Register(ISockHandler* eh, MultiplexorMask mask);

	/**
     * @brief Unregister io event.
	 * @param [eh] Handler to unregister.
	 * @exception Occurred error, throw herm::Exception.
	 */
	void Remove(ISockHandler* eh);

	/**
	 * @brief Activate some events of handler.
	 * @param [eh] Handler to activate event.
	 * @param [mask] io events. 
	 * @exception Occurred error, throw herm::Exception.
	 */
	void EnableMask(ISockHandler* eh, MultiplexorMask mask);

	/**
	 * @brief Disable some events of handler.
	 * @param [eh] Handler to disable event.
	 * @param [mask] io events. 
	 * @exception Occurred error, throw herm::Exception.
	 */
	void DisableMask(ISockHandler* eh, MultiplexorMask mask);
};
#endif

#endif

